Predicciones de NFL:
Michael Lehan (Getty Images)

¿De Qué Se Trata? 🤔

¡Bienvenidos a Predicciones de NFL, una serie donde exploramos lo necesario para hacer predicciones de NFL. En esta primera parte, El Récord, vamos a analizar cómo el récord de temporada de un equipo afecta las probabilidades de ganar.

A medida que avancemos en la serie, desarrollaremos herramientas y eventualmente construiremos modelos predictivos

Aclaración

Primero, soy relativamente nuevo en el fútbol americano, con solo tres años de experiencia viendo partidos. Aunque todavía tengo mucho por aprender, esta perspectiva fresca me permite enfocarme únicamente en los números, sin prejuicios.

Segundo, aunque menciono las apuestas, no apoyo jugar con fines de lucro. Apostar una pequeña cantidad por diversión o para seguir predicciones está bien, pero apostar para ganar dinero puede ser adictivo y dañino.

Resumen

En este artículo, exploramos si el récord de victorias y derrotas de una temporada puede predecir los resultados de los juegos. Al final, construimos un modelo de ML muy simple que predice ganadores con una precisión del 80%, cubriendo alrededor de 40 casos por año.

Los Datos

Para esta serie, usaremos los datos jugada por jugada proporcionados por nflfastR (Un gran saludo a nflverse). El conjunto de datos contiene 372 columnas de datos jugada por jugada, que abarcan desde el 09/12/1999 hasta el 29/11/2024, con un total de 26 temporadas, 6,886 juegos y 1,211,926 jugadas.

A continuación, un vistazo rápido a los datos.

Table.1: NFL Fast R Play by Play Data

play_id game_id old_game_id home_team away_team season_type week posteam posteam_type defteam side_of_field yardline_100 game_date quarter_seconds_remaining half_seconds_remaining game_seconds_remaining game_half quarter_end drive sp qtr down goal_to_go time yrdln ydstogo ydsnet desc play_type yards_gained shotgun no_huddle qb_dropback qb_kneel qb_spike qb_scramble pass_length pass_location air_yards yards_after_catch run_location run_gap field_goal_result kick_distance extra_point_result two_point_conv_result home_timeouts_remaining away_timeouts_remaining timeout timeout_team td_team td_player_name td_player_id posteam_timeouts_remaining defteam_timeouts_remaining total_home_score total_away_score posteam_score defteam_score score_differential posteam_score_post defteam_score_post score_differential_post no_score_prob opp_fg_prob opp_safety_prob opp_td_prob fg_prob safety_prob td_prob extra_point_prob two_point_conversion_prob ep epa total_home_epa total_away_epa total_home_rush_epa total_away_rush_epa total_home_pass_epa total_away_pass_epa air_epa yac_epa comp_air_epa comp_yac_epa total_home_comp_air_epa total_away_comp_air_epa total_home_comp_yac_epa total_away_comp_yac_epa total_home_raw_air_epa total_away_raw_air_epa total_home_raw_yac_epa total_away_raw_yac_epa wp def_wp home_wp away_wp wpa vegas_wpa vegas_home_wpa home_wp_post away_wp_post vegas_wp vegas_home_wp total_home_rush_wpa total_away_rush_wpa total_home_pass_wpa total_away_pass_wpa air_wpa yac_wpa comp_air_wpa comp_yac_wpa total_home_comp_air_wpa total_away_comp_air_wpa total_home_comp_yac_wpa total_away_comp_yac_wpa total_home_raw_air_wpa total_away_raw_air_wpa total_home_raw_yac_wpa total_away_raw_yac_wpa punt_blocked first_down_rush first_down_pass first_down_penalty third_down_converted third_down_failed fourth_down_converted fourth_down_failed incomplete_pass touchback interception punt_inside_twenty punt_in_endzone punt_out_of_bounds punt_downed punt_fair_catch kickoff_inside_twenty kickoff_in_endzone kickoff_out_of_bounds kickoff_downed kickoff_fair_catch fumble_forced fumble_not_forced fumble_out_of_bounds solo_tackle safety penalty tackled_for_loss fumble_lost own_kickoff_recovery own_kickoff_recovery_td qb_hit rush_attempt pass_attempt sack touchdown pass_touchdown rush_touchdown return_touchdown extra_point_attempt two_point_attempt field_goal_attempt kickoff_attempt punt_attempt fumble complete_pass assist_tackle lateral_reception lateral_rush lateral_return lateral_recovery passer_player_id passer_player_name passing_yards receiver_player_id receiver_player_name receiving_yards rusher_player_id rusher_player_name rushing_yards lateral_receiver_player_id lateral_receiver_player_name lateral_receiving_yards lateral_rusher_player_id lateral_rusher_player_name lateral_rushing_yards lateral_sack_player_id lateral_sack_player_name interception_player_id interception_player_name lateral_interception_player_id lateral_interception_player_name punt_returner_player_id punt_returner_player_name lateral_punt_returner_player_id lateral_punt_returner_player_name kickoff_returner_player_name kickoff_returner_player_id lateral_kickoff_returner_player_id lateral_kickoff_returner_player_name punter_player_id blocked_player_name tackle_for_loss_1_player_id tackle_for_loss_1_player_name tackle_for_loss_2_player_id tackle_for_loss_2_player_name qb_hit_1_player_id qb_hit_1_player_name qb_hit_2_player_id qb_hit_2_player_name forced_fumble_player_1_team forced_fumble_player_1_player_id forced_fumble_player_1_player_name forced_fumble_player_2_team forced_fumble_player_2_player_id forced_fumble_player_2_player_name solo_tackle_1_team solo_tackle_2_team solo_tackle_1_player_id solo_tackle_2_player_id solo_tackle_1_player_name solo_tackle_2_player_name assist_tackle_1_player_id assist_tackle_1_player_name assist_tackle_1_team assist_tackle_2_player_id assist_tackle_2_player_name assist_tackle_2_team assist_tackle_3_player_id assist_tackle_3_player_name assist_tackle_3_team assist_tackle_4_player_id assist_tackle_4_player_name assist_tackle_4_team tackle_with_assist tackle_with_assist_1_player_id tackle_with_assist_1_player_name tackle_with_assist_1_team tackle_with_assist_2_player_id tackle_with_assist_2_player_name tackle_with_assist_2_team pass_defense_1_player_id pass_defense_1_player_name pass_defense_2_player_id pass_defense_2_player_name fumbled_1_team fumbled_1_player_id fumbled_1_player_name fumbled_2_player_id fumbled_2_player_name fumbled_2_team fumble_recovery_1_team fumble_recovery_1_yards fumble_recovery_1_player_id fumble_recovery_1_player_name fumble_recovery_2_team fumble_recovery_2_yards fumble_recovery_2_player_id fumble_recovery_2_player_name sack_player_id sack_player_name half_sack_1_player_id half_sack_1_player_name half_sack_2_player_id half_sack_2_player_name return_team return_yards penalty_team penalty_player_id penalty_player_name penalty_yards replay_or_challenge replay_or_challenge_result penalty_type defensive_two_point_attempt defensive_two_point_conv defensive_extra_point_attempt defensive_extra_point_conv safety_player_name safety_player_id season cp cpoe series series_success series_result order_sequence start_time time_of_day stadium weather nfl_api_id play_clock play_deleted play_type_nfl special_teams_play st_play_type end_clock_time end_yard_line fixed_drive fixed_drive_result drive_real_start_time drive_play_count drive_time_of_possession drive_first_downs drive_inside20 drive_ended_with_score drive_quarter_start drive_quarter_end drive_yards_penalized drive_start_transition drive_end_transition drive_game_clock_start drive_game_clock_end drive_start_yard_line drive_end_yard_line drive_play_id_started drive_play_id_ended away_score home_score location result total spread_line total_line div_game roof surface temp wind home_coach away_coach stadium_id game_stadium aborted_play success passer passer_jersey_number rusher rusher_jersey_number receiver receiver_jersey_number pass rush first_down special play passer_id rusher_id receiver_id name jersey_number id fantasy_player_name fantasy_player_id fantasy fantasy_id out_of_bounds home_opening_kickoff qb_epa xyac_epa xyac_mean_yardage xyac_median_yardage xyac_success xyac_fd xpass pass_oe old_game_id_x nflverse_game_id old_game_id_y possession_team offense_formation offense_personnel defenders_in_box defense_personnel number_of_pass_rushers players_on_play offense_players defense_players n_offense n_defense ngs_air_yards time_to_throw was_pressure route defense_man_zone_type defense_coverage_type extra_point_count two_point_conv_count field_goal_count posteam_score_diff defteam_score_diff winning_team_type vegas_away_wp total_minutes winning_team_score losing_team_score total_minutes_rounded winning_team_score_total losing_team_score_total score_diff_total
Loading ITables v2.2.3 from the internet... (need help?)

Como puedes ver, hay mucha información que va desde yardas por pase por jugada hasta tacleadas con asistencia.

Para esta primera parte de la serie, nos enfocaremos únicamente en cómo los récords impactan los resultados actuales de los juegos. Para simplificar el conjunto de datos, lo reduciremos a la información de Las Vegas y el récord de la temporada actual.

A continuación, puedes ver una tabla más reducida que utilizaremos:

Table.2: Game Result Data by Team

season week game_id team team_type opponent_team team_score_final opponent_team_score_final is_winner_final team_score_diff_final team_vegas_wp team_vegas_spread team_is_winner_vegas_spread opponent_team_vegas_wp
Loading ITables v2.2.3 from the internet... (need help?)

Probabilidades de Las Vegas

Cuando se trata de predicciones, la mayoría de los modelos de ML se construyen para competir contra las líneas de Las Vegas. ¿Pero por qué luchar contra esto cuando podemos aprovechar la riqueza de información que Las Vegas ofrece? Claro, hay muchas casas de apuestas ofreciendo diferentes probabilidades, y las apuestas públicas probablemente distorsionen las líneas. Pero para este análisis, la línea de spread de Pro-Football-Reference debería funcionar perfectamente. Nos proporciona una buena referencia de cuán precisa puede ser Las Vegas y prepara el escenario para algunas comparaciones emocionantes.

Scores
Aaron M. Sprecher (Getty Images)

Como se muestra en Fig. 1, la precisión de Las Vegas al predecir ganadores utilizando la línea de spread fue un impresionante 66.3%.

No description has been provided for this image

Ahora, echemos un vistazo a cuán precisa es Las Vegas al proyectar al ganador según la línea de spread. Es importante notar que en esta parte de la serie, no nos estamos enfocando en el margen de puntos en sí. Esto significa que no estamos evaluando si el spread fue cubierto; solo estamos prediciendo ganadores sin importar la diferencia de puntos.

No description has been provided for this image

Como era de esperar en Fig.2, podemos ver que cuanto mayor es la diferencia proyectada de spread, más precisa es Las Vegas al predecir al ganador. Sin embargo, más del 50% de los juegos tienen una línea de spread inferior a 4 puntos, y para esos, la precisión está entre 50-60%, lo cual no es muy impresionante.

Un dato interesante: en 94 ocasiones donde Las Vegas ofreció un spread de 15 o más, solo 3 veces el equipo no favorito realmente ganó. Esos juegos fueron:

Otro juego que se destaca, y uno que recuerdo demasiado bien, fue la Semana 14 de la temporada 2023: mi equipo local, los Miami Dolphins, enfrentó a los Tennessee Titans. Miami tenía un buen récord de 9-3, mientras que los Titans estaban luchando con 4-8. Las Vegas le dio a Miami un spread de 14 puntos, pero terminamos perdiendo 28-27. Para colmo, tenía a Tyreek Hill en mi equipo de fantasía, y apenas jugó ese día 😩.


El Récord

Vamos a sumergirnos en el objetivo de este artículo y descubrir si el récord de un equipo influye en sus posibilidades de ganar.

Scores
Chris Graythen (Getty Images)

Primero, calculemos el coeficiente de correlación de Pearson de victorias y margen de victoria contra:

  • Total de Juegos (record_total_games)
  • Juegos Ganados en la Temporada (season_winning_record)
  • Juegos Perdidos en la Temporada (season_losing_record)
  • Porcentaje de Victorias en la Temporada (season_winning_ratio)
  • Juegos Ganados por el Oponente en la Temporada (opponent_season_winning_record)
  • Juegos Perdidos por el Oponente en la Temporada (opponent_season_losing_record)
  • Porcentaje de Victorias del Oponente en la Temporada (opponent_season_winning_ratio)
  • Diferencia en Porcentaje de Victorias (Porcentaje de Victorias - Porcentaje de Victorias del Oponente) (winning_ratio_diff)
  • Si el equipo está jugando en casa o no (is_home)

También incluiremos la Línea de Spread de Las Vegas para comparación.

Table.3: Is Winner/Score Diff Correlations

is_winner_final team_score_diff_final
Loading ITables v2.2.3 from the internet... (need help?)

Como era de esperar, Las Vegas sabe lo que hace: la línea de spread de Las Vegas está mucho más correlacionada con ganar y el margen de victoria que el porcentaje de victorias en juegos. Además, los porcentajes de victorias son más significativos que el récord en sí.

¿Pero qué pasa con las rachas de victorias? ¿Tienen algún impacto en la NFL?

Table.4: Is Winner/Score Diff Correlations

is_winner_final team_score_diff_final
Loading ITables v2.2.3 from the internet... (need help?)

Como se muestra en la tabla anterior, el porcentaje de victorias del oponente tiene una correlación mínima con las probabilidades de ganar. Sin embargo, las rachas largas, como 12, 13 o 14 juegos, parecen tener una influencia más significativa para determinar al ganador.

En otras palabras, tener un récord ganador o perdedor no afecta directamente el resultado de una manera notoria. Pero vamos a profundizar en los datos para ver si podemos descubrir algún patrón oculto.

No description has been provided for this image

¡Ahora sí estamos viendo algo interesante! Como podemos observar, cuando la diferencia de porcentaje de victorias es pequeña, cualquier cosa puede pasar. Pero a medida que nos movemos hacia los extremos—donde (>0.25) un gran equipo enfrenta a uno que está luchando—comenzamos a ver una tendencia clara.

Una observación interesante es que cuando la diff=1, el patrón cambia. Después de inspeccionar los datos, esto ocurre temprano en la temporada, cuando hay muchos equipos invictos o sin victorias. Entonces, intentemos filtrar los datos para incluir solo juegos después de la Semana 3.

No description has been provided for this image

Bueno, esto es algo. Vamos a verificar las correlaciones después de la Semana 3 y cuando la diferencia de porcentaje de victorias sea mayor que 0.25 o menor que -0.25.

Table.4: Is Winner/Score Diff Correlations

is_winner_final team_score_diff_final
Loading ITables v2.2.3 from the internet... (need help?)

Ahora nuestros datos se alinean estrechamente con el spread de Las Vegas, lo cual es motivador para intentar construir un modelo de ML simple. Y sí, hemos reducido significativamente nuestro conjunto de datos—de 6,898 juegos a solo 2,254 juegos—pero bueno, no siempre se puede ganar, ¿verdad? 😅

Aprendizaje Automático

Ahora intentemos crear un modelo de ML simple. Usaremos un Algoritmo de Árbol de Decisión, principalmente porque es sencillo y muy ilustrativo, y también porque tenemos un conjunto de datos muy pequeño, con menos de 10,000 puntos de datos.

ML
Chat GPT

Los árboles de decisión son un tipo de algoritmo supervisado de aprendizaje automático utilizado tanto para tareas de clasificación como de regresión. Funcionan dividiendo recursivamente los datos en subconjuntos basados en las características que proporcionan la separación más significativa según una métrica elegida. Este método es interpretable, ya que podemos visualizar cómo el árbol divide los datos y el proceso de toma de decisiones que sigue. Sin embargo, los Árboles de Decisión pueden ser propensos a sobreajustarse, especialmente con conjuntos de datos complejos, por lo que utilizaremos técnicas como limitar la profundidad del árbol para garantizar una mejor generalización.

Primero, dividiremos los datos. Usaremos datos desde 1999 hasta 2022 para entrenar nuestro Árbol de Decisión, y luego probaremos el rendimiento con los datos de 2023 y 2024.

No description has been provided for this image

Fig. 5 muestra el árbol de decisión. Optimizamos los parámetros utilizando GridSearchCV, lo que significa que probamos varias configuraciones de árbol para encontrar la que mejor funcionó. Como se muestra, el árbol tiene 3 niveles de profundidad. Primero verifica si winning_ratio_diff > -0.029, luego evalúa si winning_ratio_diff > 0.216, y finalmente considera si el equipo está jugando en casa.

Desde 1999 hasta 2022, los equipos locales con un winning_ratio_diff de 0.216 jugaron 990 juegos y ganaron 763 de ellos, logrando una impresionante tasa de victorias del 80%.

Ahora, probemos cómo habría funcionado esta regla simple en 2023 y 2024.

Como vemos arriba, de 64 casos donde se cumplió esta condición, se mantuvo la tasa de victorias del 80%. En 51 de esos casos, el equipo ganador celebró en casa 🎉🎉🎉🎉.

Ahora, pasemos a mostrar la tabla de predicciones.

Table5: Prediction Results

season week team opponent_team win_prediction is_winner team_vegas_wp team_vegas_spread team_score_final opponent_team_score_final is_home season_winning_ratio opponent_season_winning_ratio
Loading ITables v2.2.3 from the internet... (need help?)

De hecho, en la Semana 13 de 2024, podríamos haber ganado una apuesta combinada de 7 😂.

Conclusiones y Créditos

Hemos concluido la primera parte de Predicciones de NFL. Logramos un resultado sólido con un árbol de decisión simple que proporciona una tasa de éxito del 80% en los casos donde se aplicó—alrededor de 35-45 casos por año. En la siguiente parte, profundizaremos en Puntos, Spreads, y Totales.

Agradecimientos:

  • OpenAI: Sin ChatGPT, este artículo no habría sido posible—el idioma nativo del autor es el español (que apenas habla ahora 😂).
  • NFLFastR: Por proporcionar los datos para analizar la NFL.
  • Mi esposa ❤️.